/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package our.gui;

import java.awt.AWTException;
import java.awt.Dialog;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.log4j.jdbc.JDBCAppender;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 *
 * @author keysman
 */

public class utils {
    // Quando questa condizione è true, la procedure ALTER viene saltata e non viene
    // effettuato nessun salvataggio.
    //static public boolean FORCE_EXIT_WITHOUT_SAVE = false;
       
    static final public int APP_H = 600;  // Altezza applicazione
    static final public int APP_W = 750; // Larghezza in pixel dell'applicazione
    static public String DBUSER     = "admin";
    //static public String DBPASS     = "admin";
    static public String VERSION = "1.0.0";
    // I seguenti sono i parametri per la connessione al MySQL
    /*static public String DBHOST     = "127.0.0.1";
    static public String DBPORT     = "3306";
    final static String MYSQL_USER = "mydb";
    final static String MYSQL_PASS = "mydb";
    final static String MYSQL_URLPREFIX = "jdbc:mysql://";
    final static String MYSQL_DB = "/mydb";
    final static String MYSQL_DRIVER = "com.mysql.jdbc.Driver";*/
    // Timeout per il lock/unlock
    static public long LOCK_TIMEOUT = 300000L;

    //static public int ID_AZIENDA = 0; // Id azienda corrente
    //static public String MAINMENUIMAGE = null;
    //static public boolean USE_H2 = false;

    // Permessi di Modifica, Salvataggio, Inserimento, Cancellazione
    static public boolean USER_ALLOW_EDIT = false;
    static public boolean USER_ALLOW_INS = false;
    static public boolean USER_ALLOW_DEL = false;

    static private char[] _MAGIC_WORD = { 0x47, 0x69, 0x33, 0x34, 0x50, 0x69, 0x64, 0x4A};
    static private String MAGIC_WORD = new String(_MAGIC_WORD);

    static private String _CONFIG_XML = null;
    
    // Il path alla cartella contenente il file config
    static String CONFIGPATH = null;
    
//    static public SqlMapClient sqlMap;

    //static public Category logger = Category.getRoot();
    static public Logger logger;
    
    //static private JDBCAppender _JA = null;

    static public boolean LOCK_HOST_AND_PORT = false;

    static public Connection connection = null;
    static private FileHandler fh = null;

    
/*    public static SqlMapClient getSqlMapInstance()
    {
        return sqlMap;
    }*/


    public static java.awt.Rectangle centerOnVideo(int iWidth, int iHeight)
    {
        java.awt.Toolkit tk = java.awt.Toolkit.getDefaultToolkit();
        java.awt.Dimension screenSize = tk.getScreenSize();
        int iScrH = screenSize.height;
        int iScrW = screenSize.width;
        java.awt.Rectangle rect = new java.awt.Rectangle( (iScrW - iWidth) / 2, (iScrH - iHeight) / 2,
                                                          iWidth, iHeight);
        return rect;
    }

    /**
     * Converte una stringa in formato ddmmyyyy in java.util.Date.
     * ATTENZIONE: La lunghezza della stringa deve essere 8
     * @param str La stringa contenente la data in formato ddmmyyyy
     * @return Un oggetto di tipo java.util.Date
     */
    public static Date StringToDate(String str)
    {
        Date dateRet = null;

        if(str==null) return null;

        if( (str.length()==8) || (str.length()==0) )
        {
            int iDay = Integer.parseInt(str.substring(0, 2));
            int iMon = Integer.parseInt(str.substring(2, 4));
            int iYea = Integer.parseInt(str.substring(4));

            Calendar cal = new GregorianCalendar(iYea, iMon - 1, iDay);

            dateRet = new Date();
            dateRet = cal.getTime();

        } else {
            // Se sono qui è una data 'anomala'
            logger.log(Level.WARNING, "Lunghezza data non corretta");
        }

        return dateRet;
    }

    /**
     * Converte dal formato java.util.Date (yyyy-mm-dd) in formato mmddyyyy
     * @param date Data (generalmente letta dal db)
     * @return Stringa contenente la data in formato 'mmddyyyy' o "" in caso di data assente (null)
     */
    public static String DateToString(Date date)
    {
        String bRet = null;

        if(date!=null)
        {
            Calendar cal = new GregorianCalendar();
            cal.setTime(date);

            String strDay = "";
            String strMon = "";
            if(cal.get(Calendar.DATE) < 10) strDay = "0";
            strDay += "" + cal.get(Calendar.DATE);
            if(cal.get(Calendar.MONTH) < 10) strMon = "0";
            strMon += "" + (cal.get(Calendar.MONTH) + 1);
            String strYea = "" + cal.get(Calendar.YEAR);
            bRet = "" + strDay + strMon + strYea;
        }
        return bRet;
    }

    /**
     * Verifica che la data passata in formato Stringa di 4,6,8 caratteri, sia valida
     * @param aDate Data da verificare
     * @return La data formattata correttamente, null altrimenti
     */
    public static String isValidDate(String aDate)
    {
        aDate = aDate.replaceAll("/", "");
        java.util.Calendar cal = java.util.Calendar.getInstance();
        int year = cal.get(java.util.Calendar.YEAR);
        if (aDate.length() == 6) {    
            year = year / 100;
            aDate = aDate.substring(0, 4) + year + aDate.substring(4);
        }
        if(aDate.length() == 4) {
            aDate += year;
        }
        SimpleDateFormat sdf = null;
        if (aDate.length() == 8) {
            sdf = new SimpleDateFormat("ddMMyyyy");
        } else {
            sdf = new SimpleDateFormat("ddMMyy");
        }
        Date testDate = null;

        try {
            testDate = sdf.parse(aDate);
        } catch (java.text.ParseException e) {
            return null;
        }
        if (!sdf.format(testDate).equals(aDate)) {
            return null;
        }
        return aDate;
    }

    /**
     * Restituisce una stringa dal file di configurazione.
     * Esempio di parametro: main_settings.driver
     * @param strPath Il parametro da cercare
     * @return Il valore del parametro
     */
    public static String getConfigXMLParams(String strPath)
    {
        String strRet = null;
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {
            String[] strCmp = strPath.split("\\."); // Scompongo in elementi il path per l'elemento richiesto (max 2 elementi)
            if(strCmp.length!=2)
            {
                logger.log(Level.SEVERE, "Path di recerca non valido!");
                return null;
            }
            InputStream is = utils.class.getResourceAsStream(_CONFIG_XML);
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(is);
            doc.getDocumentElement().normalize();
            //System.out.println("Root element " + doc.getDocumentElement().getNodeName());
            NodeList nodeLst = null;
            boolean isMainSettings = false;
            if(strCmp[0].equalsIgnoreCase("main_settings"))
            {
                nodeLst = doc.getElementsByTagName("main_settings");
                isMainSettings = true;
            } else {
                nodeLst = doc.getElementsByTagName("form");
            }
            //System.out.println("Information about all notes");
            for(int s=0; s < nodeLst.getLength(); s++)
            {
                Node fstNode = nodeLst.item(s);
                if(fstNode.getNodeType() == Node.ELEMENT_NODE)
                {
                    Element fstElmnt = (Element)fstNode;

                    org.w3c.dom.Attr attr = fstElmnt.getAttributeNode("name");
                    if( isMainSettings || (attr!=null && attr.getValue().equalsIgnoreCase(strCmp[0])) )
                    {
                        // Il nodo in analisi è quello corretto:
                        // cerco il valore richiesto
                        NodeList fstNmElmntLst = fstElmnt.getElementsByTagName(strCmp[1]);
                        Element fstNmElmnt = (Element) fstNmElmntLst.item(0);
                        if(fstNmElmnt==null)
                        {
                            // Non esiste l'elemento
                            strRet = "";
                            break;
                        }
                        NodeList fstNm = fstNmElmnt.getChildNodes();
                        strRet = (fstNm.item(0)==null) ? "" : ((Node) fstNm.item(0)).getNodeValue();
                        break;
                    }
                }
            }
        } catch(Exception ex) {
            logger.log(Level.SEVERE, ex.toString());
            strRet = null;
        } finally {
            return strRet;
        }
    }

    /**
     * Funzione che si occupa di creare la connessione al database
     * e creare il gestore del Log
     * @param strDriver Driver per la connessione al database
     * @param strURL    URL per la connessione al database
     * @param strUser   User
     * @param strPass   Password
     */
    //public static void DBConnection(String strDriver, String strURL, String strUser, String strPass, String strLog)
    public static void Initialize(String configFile)
    {
        _CONFIG_XML = configFile;
        try {
            // Creo il gestore dei log
            LogManager lm = LogManager.getLogManager();
            fh = new FileHandler(getConfigXMLParams("main_settings.log"), true);
            logger = Logger.getLogger("ourGui Log System");
            lm.addLogger(logger);
            logger.setLevel(Level.INFO);
            fh.setFormatter(new classLogFormatter());
            logger.addHandler(fh);
            Class.forName(getConfigXMLParams("main_settings.driver"));
            connection = DriverManager.getConnection(getConfigXMLParams("main_settings.connection_string"),
                                                     getConfigXMLParams("main_settings.user"),
                                                     getConfigXMLParams("main_settings.password"));
        } catch (ClassNotFoundException ex) {
            connection = null;
            logger.log(Level.SEVERE, ex.toString());
        } catch (java.sql.SQLException ex) {
            connection = null;
            logger.log(Level.SEVERE, ex.toString());
        } catch (java.io.IOException ex) {
            connection = null;
            Logger.getLogger(utils.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Chiude la connessione al database
     */
    public static void DBClose()
    {
        try {
            if(connection!=null) connection.close();
            if(fh!=null) fh.close();
        } catch (SQLException ex) {
            logger.log(Level.SEVERE, ex.toString());
        }
    }
    
    /**
     * Effettua la connessione al database MySQL
     * @return
     */
    /*public static void MySQL_Connect(String strDriver, String strURL, String strUser, String strPass)
    {
        /*try {
            Class.forName(strDriver);
        } catch(java.lang.ClassNotFoundException e) {
            JOptionPane.showMessageDialog(null, e.toString(), "ERRORE", JOptionPane.ERROR_MESSAGE);
        }*/

        /*Properties dbprop = new Properties();
        // Creo una nuova istanza di JDBCAppender
	_JA = new JDBCAppender();
        dbprop.put("driver", strDriver);
        dbprop.put("url", strURL);
        _JA.setURL(strURL);
        _JA.setDriver(strDriver);
        dbprop.put("username", strUser);
        dbprop.put("password", strPass);
        try {
            String resource = "our/gui/dbase/SqlMapConfig.xml";
            Reader reader = Resources.getResourceAsReader(resource);
            sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader, dbprop);
        } catch (java.security.AccessControlException ace) {
            JOptionPane.showMessageDialog(null, ace.toString(), "Messaggio", JOptionPane.ERROR_MESSAGE);
        } catch(java.io.IOException e) {
            JOptionPane.showMessageDialog(null, "<html>Si è verificato un errore in:<br/><br/>File  : utils.java<br/>Classe: utils<br/>Metodo: MySQL_Connect</html>", "ERRORE", JOptionPane.ERROR_MESSAGE);
            System.exit(1);
        }
	// Imposto le opzioni più comuni
        _JA.setUser(strUser);
        _JA.setPassword(strPass);

        // Attivo il logger
        LogManager lm = LogManager.getLogManager();
        try {
            FileHandler fh = new FileHandler("ourgui.log");
            logger = Logger.getLogger("ourGUI_ExamopleLog");
            lm.addLogger(logger);
            logger.setLevel(Level.ALL);
            logger.addHandler(fh);
            //logger.addAppender(_JA);
        } catch (IOException ex) {
            Logger.getLogger(utils.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(utils.class.getName()).log(Level.SEVERE, null, ex);
        }



        //logger.addAppender(_JA);
    }*/


    /**
     * Scrive un messaggio nel log
     * @param str Il messaggio da scrivere nel
     * @param prty Priority.WARN_INT, ERROR_INT, INFO_INT
     */
    /*public static void writeToLog(String str, int prty)
    {
        String strTipo = "";

        str = str.replaceAll("[']", "\""); // Escaping

        if(str.length()>5000)
            str = str.substring(0, 5000);

        else if(prty==Priority.ERROR_INT)
            strTipo = "ERROR";
        else if(prty==Priority.INFO_INT)
            strTipo = "INFO";
        else if(prty==Priority.WARN_INT)
            strTipo = "WARN";
        else
            strTipo = "OTHER";
        
        if(prty==Priority.INFO_INT)
        {
            try {
                our.gui.utils.sqlMap.startTransaction();
                java.sql.Connection conn = our.gui.utils.sqlMap.getCurrentConnection();
                java.sql.Statement stmt = conn.createStatement();
                String query = "INSERT INTO LOG (tipo, msg, created_on, created_by) VALUES ('" + strTipo + "', '"+ str + "', current_timestamp(), '" + DBUSER + "')";
                stmt.execute(query);
                our.gui.utils.sqlMap.endTransaction();
            } catch(SQLException sqle) {
                writeToLog(sqle.toString(), Priority.ERROR_INT);
            }
        } else {
            _JA.setLayout(new PatternLayout("INSERT INTO LOG (tipo, msg, created_on, created_by) VALUES ('" + strTipo + "', '%m', current_timestamp(), '" + DBUSER + "')"));
            _JA.setSql("INSERT INTO LOG (tipo, msg, created_on, created_by) VALUES ('" + strTipo + "', '%m', current_timestamp(), '" + DBUSER + "')");

            if(prty==Priority.WARN_INT) // Inserimento, modifica o cancellazione
                logger.log(Level.WARNING, str);
            else if(prty==Priority.ERROR_INT) // Errore grave
                logger.log(Level.SEVERE, str);
            else if(prty==Priority.INFO_INT) // Errore grave
                logger.log(Level.INFO, str);
            else logger.log(Level.INFO, str);
        }
    }*/
    
    /**
     * 
     * @param str La stringa contenuta nella colonna locked del database
     * @return Array di due dimensioni contenente il nome del locker
     *         e il timestamp.
     */
    public static String[] getLockInfo(String str)
    {
        String strRet[] = str.split("@");
        return strRet;
    }
    
    /**
     * Crea la stringa da memorizzare nella colonna locked del db
     * @return La stringa
     */
    public static String buildLockString()
    {
        java.util.Date today = new java.util.Date();
        String str = our.gui.utils.DBUSER + "@";
        // Preparo la stringa da memorizzare nella colonna locked del db
        str += String.valueOf(today.getTime());
        return str;
    }
    
    /**
     * Messaggio di errore generato quando si cerca di modificare/cancellare un
     * record che è bloccato da un altro utente
     * @param strArr Array restituito da getLockInfo
     */
    public static void errorMsgLock(String[] strArr)
    {
        String strMsg = "L'utente " + strArr[0] + " ha occupato il record: riprova in seguito.";
        JOptionPane.showMessageDialog(null, strMsg, "ATTENZIONE", JOptionPane.WARNING_MESSAGE);
    }
    
    /**
     * Verifica se il lock del record corrente è scaduto
     * @param strArr Array restituito da getLockInfo
     * @return true se il lock è scaduto, false altrimenti
     */
    public static boolean isLockExpired(String[] strArr)
    {
        java.util.Date today = new java.util.Date();
        // Ora in millisecondi
        long lNow = today.getTime();
        // Converto in long il timestamp del lock
        long lTimeStamp = Long.parseLong(strArr[1]);
        // Efftuo la differenza
        long lDiff = lNow - lTimeStamp;
        // Se sono passati più di 5 minuti 
        if(lDiff>LOCK_TIMEOUT) return true;
        return false;        
    }
                
    static class zzzFXAction extends javax.swing.AbstractAction {
        private String key;
        private zzzCustomEvent customEvent;
        
        public zzzFXAction(String key, zzzCustomEvent customEvent)
        {
            this.key = key;
            this.customEvent = customEvent;
        }

        public void actionPerformed(java.awt.event.ActionEvent e) {
            if(customEvent!=null)
            {
                customEvent.esegui(key);
            }
        }
    }
    
    // Innser class
    static class zzzCustomEvent {
        public void esegui(String key)
        {
            if( key.equalsIgnoreCase("LEFT") ) 
            {
                System.out.println("Hai premuto LEFT");
            }
        }
    }
    
    /**
     * Carica dal database un messaggio di errore/info/warning
     * @param ID_MSG Messaggio da visualizzare
     * @param TYPE Usa i valori JOptionPane javax.swing.JOptionPane.(ERROR_MESSAGE | INFORMATION_MESSAGE | WARNING_MESSAGE | QUESTION_MESSAGE)
     * @return il valore restituito dalla message box
     */
    public static int MessageBox(String ID_MSG, int TYPE)
    {
        int iRet = -1;
        String strCaption = "";
        //int iType = 0;

/*        our.gui.dbase.models.Messaggi record = new our.gui.dbase.models.Messaggi();
        record.setId(ID_MSG);
        try {
            record = (our.gui.dbase.models.Messaggi)sqlMap.queryForObject("MESSAGGI.abatorgenerated_selectByPrimaryKey", record);
        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, "Caricamento messaggio fallito!", "ERRORE", JOptionPane.ERROR_MESSAGE);
            return iRet;
        }*/
        // Definisco l'oggetto JOptionPane per la visualizzazione del massaggio
        JOptionPane jop = null;
        Dialog d = null;
        switch(TYPE)
        {
            case JOptionPane.INFORMATION_MESSAGE: strCaption = "INFORMAZIONE"; break;
            case JOptionPane.ERROR_MESSAGE: strCaption = "ERRORE";       break;
            case JOptionPane.WARNING_MESSAGE: strCaption = "ATTENZIONE";   break;
        }
        if(TYPE==JOptionPane.QUESTION_MESSAGE)
        {
            //iRet = JOptionPane.showOptionDialog(null, record.getmessaggio(), "CONFERMA", TYPE, JOptionPane.QUESTION_MESSAGE, null, null, null);
            //jop = new JOptionPane(record.getmessaggio(), JOptionPane.QUESTION_MESSAGE);
            //Object[] options = { "Si", "No" };
            jop = new JOptionPane(ID_MSG, JOptionPane.QUESTION_MESSAGE,
                                  JOptionPane.YES_NO_OPTION);
            jop.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,0), "LEFT");
            jop.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,0), "RIGHT");
            jop.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0), "ENTER");
            jop.getActionMap().put("ENTER", new AbstractAction() {
                public void actionPerformed(ActionEvent ae) {
                    try {
                        java.awt.Robot robot = new java.awt.Robot();
                        robot.keyPress(KeyEvent.VK_SPACE);
                        robot.keyRelease(KeyEvent.VK_SPACE);
                    } catch (AWTException ex) {
                        Logger.getLogger(utils.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            });
            jop.getActionMap().put("LEFT", new AbstractAction() {
                public void actionPerformed(ActionEvent ae) {
                    java.awt.KeyboardFocusManager kfm = java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager();
                    kfm.focusPreviousComponent();
                }
            });
            jop.getActionMap().put("RIGHT", new AbstractAction() {
                public void actionPerformed(ActionEvent ae) {
                    java.awt.KeyboardFocusManager kfm = java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager();
                    kfm.focusNextComponent();
                }
            });
        }
        else {
            //jop = new JOptionPane(record.getmessaggio(), iType); // Testo del messaggio, Tipo messaggio
            jop = new JOptionPane(ID_MSG, TYPE, JOptionPane.DEFAULT_OPTION);
            //JOptionPane.showMessageDialog(null, record.getmessaggio(), strCaption, iType);
        }
        d = jop.createDialog(strCaption);
        d.setVisible(true);
        if(TYPE!=1)
        {
            try 
            {
                iRet = Integer.parseInt(jop.getValue().toString());
            } catch(NullPointerException npe) {
                iRet = JOptionPane.NO_OPTION;
            }
        }
        return iRet;
    }


    /**
     * Formatta un valore double con un certo numero di decimali (,) e le centinaia (.)
     * @param dVal Valore da formattare
     * @param iDecimals Numero di decimali
     * @return Stringa rappresentante il valore
     */
    public static String DoubleToString(double dVal, int iDecimals)
    {
        String strRet = null;
        // Preparo la stringa per il formatter;
        String strPat = "#,##0";
        if(iDecimals>0)
        {
            strPat += ".";
            for(int i=0; i<iDecimals + 1; i++) strPat += "0";
        }
        java.text.NumberFormat formatter = new java.text.DecimalFormat(strPat);
        strRet = formatter.format(dVal);
        // Il seguente assegnamento è stato effettuato per eventuali cifre del tipo 0,000
        int iLastDot = strRet.lastIndexOf(".")==-1 ? strRet.lastIndexOf(",") : strRet.lastIndexOf(".");
        strRet = strRet.replaceAll(",", ".");
        strRet = strRet.substring(0, iLastDot) + "," + strRet.substring(iLastDot + 1);
        return strRet.substring(0, strRet.length() - 1);
    }

    /**
     * Formatta una stringa contenente un valore double con un certo numero di decimali (,) e le centinaia (.)
     * @param strVal La stringa contenente un valore dubule
     * @param iDecimals Numero di decimali
     * @return La stringa formattata
     */
    public static String StringLikeDouble(String strVal, int iDecimals)
    {
        String strRet = null;
        try {
            if(strVal.indexOf("E")>=0)
            {
                String strPat = "#,##0";
                if(iDecimals>0)
                {
                    strPat += "."; // Aggiungo +1 per evitare l'arrotondamento
                    for(int i=0; i<iDecimals + 1; i++) strPat += "0";
                }
                java.text.NumberFormat formatter = new java.text.DecimalFormat(strPat);
                strVal = formatter.format(Double.parseDouble(strVal));
                //strVal = strVal.replaceAll("[,]", "");
                strVal = strVal.replace(",", "#");
                strVal = strVal.replaceAll("[.]", ",");
                strVal = strVal.replace("#", ".");
                strRet = strVal;
                return strRet;
            }
            if(strVal.isEmpty()) strVal="0.0"; // Se la stringa è vuoto imposto il valore a 0
            if( (strVal.lastIndexOf(".")==strVal.indexOf(".")) && (strVal.indexOf(",")<0) )
                strVal = strVal.replace(".", ",");
            strVal = strVal.replace(",", "#");
            strVal = strVal.replaceAll("[.]", "");
            strVal = strVal.replace("#", ".");
            double dVal = Double.parseDouble(strVal);
            // Preparo la stringa per il formatter;
            String strPat = "#,##0";
            if(iDecimals>0)
            {
                strPat += "."; // Aggiungo +1 per evitare l'arrotondamento
                for(int i=0; i<iDecimals + 1; i++) strPat += "0";
            }
            java.text.NumberFormat formatter = new java.text.DecimalFormat(strPat);
            strRet = formatter.format(dVal);
            // Il seguente assegnamento è stato effettuato per eventuali cifre del tipo 0,000
            int iLastDot = strRet.lastIndexOf(".")==-1 ? strRet.lastIndexOf(",") : strRet.lastIndexOf(".");
            strRet = strRet.replaceAll(",", ".");
            strRet = strRet.substring(0, iLastDot) + "," + strRet.substring(iLastDot + 1);
            strRet = strRet.substring(0, strRet.length()-1);
        } catch(java.lang.NumberFormatException nfe) {
            Logger.getLogger(utils.class.getName()).log(Level.SEVERE, null, nfe);
        } finally {
            return strRet;
        }
    }

    /**
     * Converte un valore di tipo String in double.
     * Il formato della stringa deve essere: 1.000,0 oppure 10,10 oppure 1.000.123,12 ecc ecc
     * @param strVal Il valore da convertire
     * @return
     */
    public static Double StringToDouble(String strVal)
    {
        if(strVal.indexOf("E")>=0) return Double.parseDouble(strVal);
        double dRet = 0.0;
        if(strVal==null || strVal.length()==0) return 0.0;
        if(strVal.startsWith(",")) strVal = "0" + strVal; // Se la stringa parte con la , aggiungo uno 0 in testa
        if(strVal.indexOf(",")<0) strVal += ",00";
        try {
            String strTmp = strVal.replaceAll("[.]", "");
            strTmp = strTmp.replaceAll("[,]", "."); // Le virgole le rimpiazzo con il punto
            dRet = Double.parseDouble(strTmp);
        } catch(java.lang.NumberFormatException nfe) {
            Logger.getLogger(utils.class.getName()).log(Level.SEVERE, null, nfe);
        } finally {
            return dRet;
        }
    }
}
